import json
from datetime import datetime
import sys
import time
from fastapi import FastAPI, Request, APIRouter, Form, status
from fastapi.responses import PlainTextResponse
from api.routes.login import get_current_user
from core.WXBizMsgCrypt3 import WXBizMsgCrypt
import xml.etree.cElementTree as ET
import redis
import core.wechat_utils as wechat_utils
from db.database_utils import DatabaseUtils
import configparser
from model.Config import Config
from model.Ai import Ai
from model.SystemConfig import SystemConfig
config = configparser.ConfigParser()
config.read('core/config.properties')
corpid = config.get('weixin', 'corpid')
corpsecret = config.get('weixin', 'corpsecret')
print(corpid, corpsecret)

router = APIRouter()
app = FastAPI()

sToken = None
sEncodingAESKey = None
sCorpID = None
sAppId = None
corpSecret = None

db_utils = DatabaseUtils(
    "mysql+pymysql://root:123456@" + Config.instance.get_db_host() + ":3306/weixin?charset=utf8mb4")

# 创建Redis连接
redis_pool = redis.ConnectionPool(host=Config.instance.get_redis_host(), port=6379, password=None, db=0)
# 创建 Redis 连接对象，使用连接池
redis_conn = redis.Redis(connection_pool=redis_pool)


@router.get("/verify_callback_url")
def verify_callback_url(request: Request):
    query_params = request.query_params
    sVerifyMsgSig = query_params.get("msg_signature")
    sVerifyTimeStamp = query_params.get("timestamp")
    sVerifyNonce = query_params.get("nonce")
    sVerifyEchoStr = query_params.get("echostr")
    wxcpt = WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID)

    ret, sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, sVerifyEchoStr)
    if ret != 0:
        print("ERR: VerifyURL ret: " + str(ret))
        return {"errcode": ret}
    response = PlainTextResponse(sEchoStr)
    print(response)
    return response


@router.post("/verify_callback_url")
async def process_robot_message(request: Request):
    from_user_name = None
    create_time = None
    content = None
    error_msg = None
    to_user_name = None
    try:
        print("---------------开始解析-------------------")

        # 获取相关参数
        msg_signature = request.query_params.get('msg_signature')
        timestamp = request.query_params.get('timestamp')
        nonce = request.query_params.get('nonce')
        wxcpt = WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID)
        # 解密信息
        body = await request.body()
        body_str = body.decode('utf-8')
        ret, sMsg = wxcpt.DecryptMsg(body_str, msg_signature, timestamp, nonce)
        print("---------------解析完成-------------------")

        # 解析信息内容
        root = ET.fromstring(sMsg)

        # 获取每个元素的值
        to_user_name = root.find('ToUserName').text if root.find('ToUserName') is not None else None
        from_user_name = root.find('FromUserName').text if root.find('FromUserName') is not None else None
        create_time = root.find('CreateTime').text if root.find('CreateTime') is not None else None
        msg_type = root.find('MsgType').text if root.find('MsgType') is not None else None
        content_element = root.find('Content')
        content = content_element.text if content_element is not None else None
        print("---------------信息获取完成------------------")

        # 格式化datetime对象为指定的字符串格式
        formatted_dt = datetime.fromtimestamp(int(create_time) * 1000 / 1000.0).strftime('%Y-%m-%d %H:%M:%S')
        if msg_type == "text" and content is not None:
            get_access_token = wechat_utils.get_access_token(sCorpID, corpSecret, "core/access_token.json")
            user_name = wechat_utils.get_user_info(get_access_token, from_user_name)["name"]
            # 接入AI
            print(Ai.ai_url)
            if Ai.ai_url is not None:
                reply_content = Ai.query(content)["data"]['result'][Ai.output_name]
            else:
                reply_content = SystemConfig.template.replace("{消息}", content).replace("{日期}", formatted_dt).replace("{姓名}", user_name)

           
                  
            print(reply_content)
            # 写入数据库
            query = f"""
            INSERT INTO
            `weixin`.`message`
            (`create_time`,`user_name`,`content`)
            VALUES
            ("{create_time}","{user_name}","{content}");"""
            db_utils.execute_insert(query)

            print("---------------写入数据库成功---------------")
            # 写入redis
            print(from_user_name + str(formatted_dt))
            # write_to_redis(str(formatted_dt)+from_user_name, '"'+content+'"', 0, 6379)
            value = {
                "create_time": str(formatted_dt),
                "user_name": user_name,
                "content": content,
                "from_user_name":from_user_name
            }
            redis_conn.lpush('list', json.dumps(value))
            print("---------------写入redis成功---------------")
            # 判断是否需要回复
            if SystemConfig.template == "None":
                return None
            # 发送消息
            print(wechat_utils.send_app_message_text(get_access_token, from_user_name, sAppId, reply_content))
            print("---------------回复消息成功---------------")
           
            return PlainTextResponse("", status_code=status.HTTP_200_OK)
        else:
            content = "不是文本消息"
            print("不是文本消息")
    except Exception as e:
        print(e)
        error_msg = str(e)
    # 构建消息
    sRespData = f"""  
    <xml>  
       <ToUserName><![CDATA[{from_user_name}]]></ToUserName>  
       <FromUserName><![CDATA[{to_user_name}]]></FromUserName>  
       <CreateTime>{create_time}</CreateTime>  
       <MsgType><![CDATA[{"text"}]]></MsgType>  
       <Content><![CDATA[{error_msg}]]></Content>  
    </xml>  
    """

    ret, sEncryptMsg = wxcpt.EncryptMsg(sRespData, nonce, timestamp)
    # 加密失败
    if ret != 0:
        print("ERR: EncryptMsg ret: " + str(ret))
        sys.exit(1)
    # 加密成功
    else:
        # 响应数据
        response = PlainTextResponse(sEncryptMsg)
        return response





# 配置信息录入
@router.post("/verification_config_ai")
async def verification_config_message(request: Request):
    query_params = await request.json()
    Ai.ai_url = query_params.get("ai_url") 
    Ai.authorization = query_params.get("authorization")
    Ai.input_name = query_params.get("input_name")   
    Ai.output_name = query_params.get("output_name") 
    print(Ai.ai_url)
    return {"status": "success","code":200}

# 配置消息模板
@router.post("/system_config")
async def system_config(request: Request):
    query_params = await request.json()
    SystemConfig.template = query_params.get("template") 
    return {"msg": "ok", "code": 200}

# 配置信息录入
@router.post("/verification_config_message")
async def verification_config_message(
        appID: str = Form(...),  # 必填字段，对应前端 input 的 name="url"
        token: str = Form(...),
        corpID: str = Form(...),
        CorpSecret: str = Form(...),
        EncodingAESKey: str = Form(...)  # 必填字段，对应前端 input 的 name="EncodingAESKey"
):
    Config.instance.set_sAppId(appID)
    Config.instance.set_sToken(token)
    Config.instance.set_sEncodingAESKey(EncodingAESKey)
    Config.instance.set_sCorpID(corpID)
    Config.instance.set_corpSecret(CorpSecret)
    print(Config.instance.get_sAppId(), Config.instance.get_sToken(), Config.instance.get_sEncodingAESKey(),
          Config.instance.get_sCorpID(), Config.instance.get_corpSecret())
    # 配置初始化完成
    global sToken, sEncodingAESKey, sCorpID, sAppId, corpSecret
    sAppId = appID
    sToken = token
    sEncodingAESKey = EncodingAESKey
    sCorpID = corpID
    corpSecret = CorpSecret
    print(sToken, sEncodingAESKey, sCorpID, corpSecret, sAppId)
    return {"status": "success"}


def write_to_redis(key, value, redis_db, redis_port):
    # 连接到Redis服务器
    redis_host = 'localhost'  # Redis服务器地址
    # redis_host = 'redis'  # Redis服务器地址
    # redis_port = 6379  # Redis服务器端口
    # redis_db = 0  # Redis数据库索引
    print(redis_host)
    redis_client = redis.Redis(host=redis_host, port=redis_port, db=redis_db)

    # 将数据写入Redis
    redis_client.set(key, value)

    print(f"Data '{value}' has been written to Redis with key '{key}'.")


@router.get("/messages")
async def get_messages():
    query = """
    SELECT `message`.`id`,
        `message`.`create_time`,
        `message`.`user_name`,
        `message`.`content`
    FROM `weixin`.`message`;
    """
    result = db_utils.execute_query(query)
    # 将元组列表转换为字典列表
    result = [{'id': row[0], 'create_time': row[1], 'user_name': row[2], 'content': row[3]} for row in result]
    return result


@router.get("/message_records")
async def get_messages(request: Request, page: int = 1, size: int = 10, ):
    # 身份验证
    token = request.cookies.get('access_token')
    await get_current_user(token)
    # 计算起始记录的索引
    start = (page - 1) * size

    # 构造查询语句
    query = f"""
    SELECT `message`.`id`,
        `message`.`create_time`,
        `message`.`user_name`,
        `message`.`content`
    FROM `weixin`.`message`
    LIMIT {start}, {size};
    """

    # 执行查询
    result = db_utils.execute_query(query)

    # 将元组列表转换为字典列表
    result = [{'id': row[0], 'create_time': row[1], 'user_name': row[2], 'content': row[3]} for row in result]

    return result


@router.get("/getRecordNum")
async def get_messages():
    # 构造查询语句
    query = f"""
    SELECT count(*) as count
    FROM `weixin`.`message`;
    """
    result = db_utils.execute_query(query)
    print(result)
    return result[0][0]


@router.get("/weworktest")
def test(request: Request):
    # print(sToken, sEncodingAESKey, sCorpID, corpsecret)
    # 处理数据
    time.sleep(2)
    return {"status": "success"}

@router.post("/send_message_to_user")
async def test(request: Request):
    try:
         
        query_params = await request.json()
        global corpSecret
        if corpSecret == query_params.get("corpSecret"):
            get_access_token = wechat_utils.get_access_token(sCorpID, corpSecret, "core/access_token.json")
            wechat_utils.send_app_message_text(get_access_token, query_params.get("from_user_name"), query_params.get("sAppId"), query_params.get("content"))
            return {"status": 200}
        return {"err": "验证信息错误"}
    except Exception as e:  
        # 捕获异常并返回错误信息  
        return HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))  
#
if __name__ == "__main__":
    pass
